package de.uni_mannheim;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.io.FileUtils;
import org.xml.sax.SAXException;

public class Converter {
	public static final String BASE_DIR = "/home/bernhard/DataMining";
	// private static Logger logger =
	// Logger.getLogger(Converter.class.getName());

	public static final String[] TEAM_STATS_ELEMENTS = new String[] { "team-metadata", "name", "team-stats",
			"team-stats-soccer", "stats-soccer-offensive", "stats-soccer-defensive", "stats-soccer-foul" };

	public static final String[] TEAM_STATS_COLUMNS = new String[] { "event-key", "team-key", "full", "points",
			"score", "opponentScore", "alignment", "shots-total", "shots-on-goal-total", "saves", "offsides",
			"imp:yellow-cards", "imp:yellow-red-cards", "imp:red-cards", "fouls-committed", "fouls-suffered",
			"imp:handballs", "imp:average-age", "imp:duels-won", "imp:duels-lost", "imp:duels-won-percentage",
			"imp:passes-completed", "imp:passes-completions-percentage", "imp:passes-failed",
			"imp:passes-failed-percentage", "imp:balls-touched", "imp:balls-touched-percentage", "corner-kicks",
			"imp:corner-kicks-left", "imp:corner-kicks-right", "imp:shots-total-outside-box",
			"imp:shots-total-inside-box", "imp:shots-foot-inside-box", "imp:shots-foot-outside-box",
			"imp:shots-total-header", "imp:crosses", "imp:crosses-left", "imp:crosses-right", "imp:freekicks",
			"imp:tracking-distance", "imp:tracking-max-speed", "imp:tracking-sprints", "imp:tracking-sprints-distance",
			"imp:tracking-fast-runs", "imp:tracking-fast-runs-distance" };

	public static final String[] TEAM_STATS_COLUMN_NAMES = new String[] { "event-key", "team-key", "team-name",
			"points", "ownScore", "opponentScore", "alignment", "shots-total", "shots-on-goal-total", "saves",
			"offsides", "yellow-cards", "yellow-red-cards", "red-cards", "fouls-committed", "fouls-suffered",
			"handballs", "average-age", "duels-won", "duels-lost", "duels-won-percentage", "passes-completed",
			"passes-completions-percentage", "passes-failed", "passes-failed-percentage", "balls-touched",
			"balls-touched-percentage", "corner-kicks", "corner-kicks-left", "corner-kicks-right",
			"shots-total-outside-box", "shots-total-inside-box", "shots-foot-inside-box", "shots-foot-outside-box",
			"shots-total-header", "crosses", "crosses-left", "crosses-right", "freekicks", "tracking-distance",
			"tracking-max-speed", "tracking-sprints", "tracking-sprints-distance", "tracking-fast-runs",
			"tracking-fast-runs-distance" };

	private static final String DRAW = "1";

	private static final String POINTS = "points";

	private static final String LOOSE = "0";

	private static final String WIN = "3";

	public static void main(String[] args) throws IOException, JAXBException, ParserConfigurationException,
			SAXException {
		int fromYear = 2008;
		int toYear = 2012;

		File matchStats = new File(BASE_DIR + File.separatorChar + "MatchStats" + fromYear + "-" + toYear + ".csv");
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(matchStats), "UTF-8"));

		writeColumnHeaders(writer);
		writeRows(writer, fromYear, toYear);

		writer.flush();
		writer.close();

	}

	private static void writeRows(Writer writer, int fromYear, int toYear) throws ParserConfigurationException,
			SAXException, IOException {
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser saxParser = factory.newSAXParser();
		for (int year = fromYear; year <= toYear; year++) {

			List<Integer> matchIds = getMatchIdsOfYear(year);
			for (Integer matchId : matchIds) {
				File teamStatsFile = getTeamStatsFile(year, matchId);
				if (!teamStatsFile.canRead()) {
					continue;
				}
				TeamStatsSaxHandler handler = new TeamStatsSaxHandler();
				saxParser.parse(teamStatsFile, handler);
				Map<String, String> team1Stat = handler.getTeam1Stat();
				Map<String, String> team2Stat = handler.getTeam2Stat();

				int team1Score = Integer.parseInt(team1Stat.get("score"));
				int team2Score = Integer.parseInt(team2Stat.get("score"));
				if (team1Score > team2Score) {
					team1Stat.put(POINTS, WIN);
					team2Stat.put(POINTS, LOOSE);
				} else if (team1Score < team2Score) {
					team1Stat.put(POINTS, LOOSE);
					team2Stat.put(POINTS, WIN);
				} else {
					team1Stat.put(POINTS, DRAW);
					team2Stat.put(POINTS, DRAW);
				}

				appendRowToFile(writer, team1Stat);
				appendRowToFile(writer, team2Stat);
			}
		}

	}

	private static void appendRowToFile(Writer writer, Map<String, String> teamStat) throws IOException {
		for (int i = 0; i < TEAM_STATS_COLUMNS.length; i++) {
			String key = TEAM_STATS_COLUMNS[i];
			String value = teamStat.get(key);
			if (key.contains("tracking") || key.contains("freekicks")) {
				// special treatment for tracking and freekicks where a lot of
				// null values or faulty zeros occur
				if (value == null || value.equalsIgnoreCase("0") || value.equalsIgnoreCase("0.0")
						|| value.equalsIgnoreCase("0.00")) {
					value = "";
				}
			}

			writer.append(value);
			if (i != TEAM_STATS_COLUMNS.length - 1) {
				writer.append("\t");
			}
		}
		writer.append("\n");
	}

	private static void writeColumnHeaders(Writer writer) throws IOException {
		for (int i = 0; i < TEAM_STATS_COLUMN_NAMES.length; i++) {
			writer.append(TEAM_STATS_COLUMN_NAMES[i]);
			if (i != TEAM_STATS_COLUMN_NAMES.length - 1) {
				writer.append("\t");
			}
		}
		writer.append("\n");
	}

	// public static SportsContent unmarshal(File inputStream) throws
	// JAXBException {
	// String packageName = SportsContent.class.getPackage().getName();
	// JAXBContext jc = JAXBContext.newInstance(packageName);
	// Unmarshaller u = jc.createUnmarshaller();
	// SportsContent doc = (SportsContent) u.unmarshal(inputStream);
	// return doc;
	// }

	private static List<Integer> getMatchIdsOfYear(int year) throws IOException {
		File file = new File(BASE_DIR + File.separatorChar + "matchIds" + year + ".txt");
		List<String> lines = FileUtils.readLines(file);
		List<Integer> matchIds = new ArrayList<Integer>(lines.size());
		for (String line : lines) {
			matchIds.add(Integer.parseInt(line));
		}
		return matchIds;
	}

	private static File getTeamStatsFile(int year, int matchId) {
		// "F:\DataMining\matches2012\138100\team_stats_138100.xml"
		return new File(BASE_DIR + File.separatorChar + "matches" + year + File.separatorChar + matchId
				+ File.separatorChar + "team_stats_" + matchId + ".xml");
	}

}
